# 24. 对象、类名称空间,组合
# 对象/类名称空间
说到对象/类名称空间,那就要先了解一下类跟对象的运行结构
class so:
name = "人类"
age = "一百岁左右"
faile = "信仰"
def __init__(self,nameb,ageb,faileb):
self.nameb = nameb
self.ageb = ageb
self.faileb = faileb
def wo(self):
print("人与人的区别到底是什么")
def eo(self):
print("你说的,明天会更好")
ll = so("江心",18,"唯我")
##这里就用话来简单写点执行过程
#============================当程序执行时遇到类时产生的类名称空间存储的数据============================
程序执行,从头到尾
遇到so类,执行so类以下可以被执行的代码--这里被执行就会生成一个类名称空间
遇到name变量,执行并记录在类名称空间中
遇到age变量,执行并记录在类名称空间中
遇到faile变量,执行并记录在类名称空间中
遇到__init__方法,记录保存内存地址
遇到wo方法,记录保存内存地址
遇到eo方法,记录保存内存地址
#============================当类加()执行赋值给变量时,会执行实例化过程============================
当类进入实例化过程时会生成一个空间,称为实例化空间,也叫做对象名称空间
将生成的实例化空间的内存地址返回给init函数中的self参数
将so()括号中的数据传递给init方法中的参数,并执行记录在实例化空间
当传递完毕,实例化空间会自动生成一个指示牌(用于保存类对象指针),有了指示牌实例化空间才能找到类名称空间,开始封闭空间,并把内存地址赋值给变量ll
注意:如果有多个实例化过程,那么产生的多个实例化空间之间都是单独的个体对象
# 查询顺序
类跟对象查询数据的顺序
nameb = "凡"
class so:
name = "人类"
age = "一百岁左右"
faile = "信仰"
def __init__(self,nameb,ageb,faileb):
self.nameb = nameb
self.ageb = ageb
self.faileb = faileb
def wo(self):
print("人与人的区别到底是什么")
def eo(self):
print("你说的,明天会更好")
对象.属性 : 先从对象空间找,如果找不到,再从类空间找,再找不到,再从父类找....
ll = so("江心",18,"唯我") print(ll.name) 执行结果: 人类
以上实例,对象如果在当前方法中找不到,那就会去类空间找
类名.属性 : 先从本类空间找,如果找不到,再从父类找....
ll = so("江心",18,"唯我") print(so.nameb) 执行结果: AttributeError: type object 'so' has no attribute 'nameb' #报错
以上实例,类如果在当前类中找不到,就会去父类找,如果找不到报错
# 小练习
计算程序中实例化多少次
class so:
name = "人类"
age = "一百岁左右"
faile = "信仰"
count = 0
def __init__(self,nameb,ageb,faileb):
self.nameb = nameb
self.ageb = ageb
self.faileb = faileb
so.count += 1
def wo(self):
print("人与人的区别到底是什么")
def eo(self):
print("你说的,明天会更好")
ll1 = so("江心",18,"唯我")
ll2 = so("江凡",13,"唯我")
ll3 = so("江空",23,"唯我")
print(so.count)
注意:在对象引用类中的静态变量时,只能查询,不能增删改操作,如果要使用对象进行修改类中的变量,那么可以修改成功,在实例化一个对象来查看这个类的变量时,就会发现这个类的变量还是原先的值
总结:可以使用对象进行操作,不过操作的结果是记录在了该对象的实例化空间,不会影响到类空间里面记录的静态数据
# 进阶题 (看组合之前必须先做)
# 要求
模拟英雄联盟写一个游戏人物的类
要求:
(1)创建一个 Game_role的类.
(2) 构造方法中给对象封装name,ad(攻击力),hp(血量).三个属性.
(3) 创建一个attack方法,此方法是实例化两个对象,互相攻击的功能:
例: 实例化一个对象 盖伦,ad为10, hp为100
实例化另个一个对象 剑豪 ad为20, hp为80
盖伦通过attack方法攻击剑豪,此方法要完成 '谁攻击谁,谁掉了多少血, 还剩多少血'的提示功能.
# 答案
class so:
def __init__(self,name,ad,hp):
self.name = name
self.ad = ad
self.hp = hp
def wo(self,amdc):
amdc.hp = amdc.hp - self.ad
print(
"""
攻击提示:
你的英雄%s攻击了对方英雄%s
对方英雄%s,掉了%s滴血
对方英雄%s,还剩下%s滴血
"""
%(self.name,amdc.name,amdc.name,self.ad,amdc.name,amdc.hp)
)
amdc1 = so("盖伦",10,100)
amdc2 = so("剑豪",20,80)
amdc1.wo(amdc2)
# 组合
组合是什么:给一个类的对象封装一个属性,这个属性是另一个类的对象,组合的原理就完全包含在这话中,接下来要深入下面的实验来理解组合的用法
# 实验
在上面进阶题为基础,新增武器系统
# 从网上截个来的
class GameRole:
def __init__(self, name, ad, hp):
self.name = name
self.ad = ad
self.hp = hp
def attack(self,p):
p.hp = p.hp - self.ad
print('%s 攻击 %s,%s 掉了%s血,还剩%s血' %(self.name,p.name,p.name,self.ad,p.hp))
def armament_weapon(self,wea):
self.wea = wea
class Weapon:
def __init__(self,name,ad):
self.name = name
self.ad = ad
def fight(self,p1,p2):
p2.hp = p2.hp - self.ad
print('%s 用%s打了%s,%s 掉了%s血,还剩%s血'\
% (p1.name,self.name,p2.name,p2.name,self.ad,p2.hp))
p1 = GameRole('大阳哥',20,500)
p2 = GameRole('印度阿宁',50,200)
axe = Weapon('三板斧',60)
broadsword = Weapon('屠龙宝刀',100)
p1.armament_weapon(axe) # 给大阳哥 装备了三板斧这个对象.
p1.wea.fight(p1,p2)
比较重点的点
- axe:是通过实例化出来的变量,就是说这个变量中其实是实例化空间的内存地址
- 先把axe变量传递给GameRole类中的armament_weapon方法中
- 在通过p1来调用armament_weapon方法中的wea变量来调用Weapon类中的fight方法
# 博主写的
class weapon:
def __init__(self,name,ap):
self.name = name
self.ap = ap
class so:
def __init__(self,name,ad,hp):
self.name = name
self.ad = ad
self.hp = hp
def wo(self,amdc,wea):
self.weapon(wea)
amdc.hp = amdc.hp - (self.ad + self.weapon.ap )
ad = self.ad + self.weapon.ap
print(
"""
攻击提示:
你的英雄%s使用%s攻击对方英雄%s
对方英雄%s,掉了%s滴血
对方英雄%s,还剩下%s滴血
"""
%(self.name,self.weapon.name,amdc.name,amdc.name,ad,amdc.name,amdc.hp)
)
def weapon(self,wea):
self.weapon = wea
dagger = weapon("短剑",60)
dorans = weapon("多兰之刃",120)
stormblade = weapon("暴风之剑",180)
amdc1 = so("盖伦",10,100)
amdc2 = so("剑豪",20,80)
amdc2.wo(amdc1,dagger)
以上的实验跟上一个的实验小异大同
← 23. 面向对象初始 25. 继承 →